<?php

namespace app\utils\base\plugin;

class P_file
{
    /**
     * 获取远程资源内容
     * @param string $paramObj
     * @return array
     */
    public function getRemoteContent($paramObj="") {
        $dataObj=paramsObj();
        $dataObj->request=paramsObj();
        $dataObj->data=paramsObj();
        $dataObj->result=array();

        $final_arr=logInit();
        if($final_arr["error_no"]==0){
            $mixed=parseToArr($paramObj,"mixed",0);
            $params=parseToArr($paramObj,"params",array());
            $messages=parseToArr($paramObj,"messages",array());
            $rules=array(
                'url' => 'require',
                'type' => '',
            );
            $dataDefault=array();
            $paramsObj=paramsObj();
            $paramsObj->params=$params;
            $paramsObj->mixed=$mixed;
            $paramsObj->rules=$rules;
            $paramsObj->messages=$messages;
            $paramsObj->dataDefault=$dataDefault;
            $checkResult = app("verifyParam")::validatorRequest($paramsObj);
            if($checkResult["error_no"]==0){
                $dataObj->request=$checkResult["result"];
            }else{
                $final_arr=logCallErrorMsg($final_arr,$checkResult);
            }
        }
        if($final_arr["error_no"]==0){
            if($dataObj->request->type=="1"){
                $paramsObj=paramsObj();
                $paramsObj->params=array(
                    "submitUrl"=>$dataObj->request->url,
                    "method"=>"get",
                    "time"=>0,
                );
                $checkResult=app("P_http")->send($paramsObj);
                if($checkResult["error_no"]==0){
                    $result=$checkResult["result"];
                    if($result["httpCode"]=="200"){
                        $final_arr["result"]=base64_encode($result["body"]);
                    }else{
                        $final_arr=recordLogMsgLevelTwo(app("errorLevel")::E_WARNING,app("errorCode")::OP_FAIL,lang("sys.opFail"),$result["error_msg"]);
                    }
                }else{
                    $final_arr=logCallErrorMsg($final_arr,$checkResult);
                }
            }else if($dataObj->request->type=="2"){
                $arrContextOptions=array(
                    "ssl"=>array(
                        "verify_peer"=>false,
                        "verify_peer_name"=>false,
                    ),
                );
                $final_arr["result"]=base64_encode(file_get_contents($dataObj->request->url,false,stream_context_create($arrContextOptions)));
            }else if($dataObj->request->type=="3"){
                $handle=fopen($dataObj->request->url,"rb");
                $content="";
                while($chunk=fread($handle,8192)){
                    $content.=$chunk;
                }
                $final_arr["result"]=base64_encode($content);
            }else{
                $final_arr=recordLogMsgLevelTwo(app("errorLevel")::E_WARNING,app("errorCode")::OP_FAIL,lang("sys.opFail"),"类型不正确");
            }
        }
        return $final_arr;
    }

    /**
     * 文件生成
     * @param string $paramObj
     * @return array
     */
    public function fileWrite($paramObj="") {
        $dataObj=paramsObj();
        $dataObj->request=paramsObj();
        $dataObj->data=paramsObj();
        $dataObj->result=array();

        $final_arr=logInit();
        if($final_arr["error_no"]==0){
            $mixed=parseToArr($paramObj,"mixed",0);
            $params=parseToArr($paramObj,"params",array());
            $messages=parseToArr($paramObj,"messages",array());
            $rules=array(
                'rootPath' => 'require',
                'relativePath' => 'require',
                'name' => 'require',
                'data' => 'require',
                'encoded' => '',
                'mode' => '',
            );
            $dataDefault=array();
            $dataDefault["mode"]="w";
            $paramsObj=paramsObj();
            $paramsObj->params=$params;
            $paramsObj->mixed=$mixed;
            $paramsObj->rules=$rules;
            $paramsObj->messages=$messages;
            $paramsObj->dataDefault=$dataDefault;
            $checkResult = app("verifyParam")::validatorRequest($paramsObj);
            if($checkResult["error_no"]==0){
                $dataObj->request=$checkResult["result"];
            }else{
                $final_arr=logCallErrorMsg($final_arr,$checkResult);
            }
        }
        if($final_arr["error_no"]==0){
            $fullPath=$dataObj->request->rootPath.$dataObj->request->relativePath;
            $this->mkdir($fullPath);
            $outputFile=$fullPath."/".$dataObj->request->name;
            if($this->isWritable($fullPath)){
                if(!$fp = fopen($outputFile,$dataObj->request->mode)){
                    $final_arr=recordLogMsgLevelTwo(app("errorLevel")::E_WARNING,app("errorCode")::OP_FAIL,lang("file.cannotOpenFile"));
                }
                if($final_arr["error_no"]==0){
                    if (flock($fp, LOCK_EX)) {
                        if($final_arr["error_no"]==0){
                            if($dataObj->request->encoded=="base64_encode"){
                                if (fwrite($fp,base64_decode($dataObj->request->data)) === FALSE) {
                                    $final_arr=recordLogMsgLevelTwo(app("errorLevel")::E_WARNING,app("errorCode")::OP_FAIL,lang("file.cannotWriteToFile"));
                                }
                            }else{
                                if (fwrite($fp,$dataObj->request->data) === FALSE) {
                                    $final_arr=recordLogMsgLevelTwo(app("errorLevel")::E_WARNING,app("errorCode")::OP_FAIL,lang("file.cannotWriteToFile"));
                                }
                            }
                        }
                        if($final_arr["error_no"]==0){
                            $host=config("app.url","");
                            $return=array();
                            $return["filePath"]=$outputFile;
                            $return["relativePath"]=$dataObj->request->relativePath."/".$dataObj->request->name;
                            $return["urlPath"]=$host."/".$return["relativePath"];
                            $final_arr["result"]=$return;
                        }
                        flock($fp, LOCK_UN);    // 释放锁定
                    }else{
                        $final_arr=recordLogMsgLevelTwo(app("errorLevel")::E_WARNING,app("errorCode")::OP_FAIL,lang("file.failedToLockFile"));
                    }
                    fclose($fp);
                }
            }else{
                $final_arr=recordLogMsgLevelTwo(app("errorLevel")::E_WARNING,app("errorCode")::OP_FAIL,lang("file.fileIsNotWritable"));
            }
        }
        return $final_arr;
    }

    /**
     * 创建目录
     * @param $dir
     */
    public function mkdir($dir){
        if(!is_dir($dir)){
            @umask(000);
            return @mkdir($dir,0777,true);
        }
        return true;
    }

    /**
     * 判断目录或文件是否可写
     * @param $dir
     */
    public function isWritable($dir){
        return is_writable($dir);
    }

    /**
     * 获取上传文件类型
     * @param string $filename 目标文件
     * @return string $ext 文件类型
     */
    private function getFileType($filename){
        $ext = pathinfo($filename, PATHINFO_EXTENSION);
        return $ext;
    }

    /**
     * 文件上传
     * @param string $paramObj
     * @return array
     */
    public function fileUpload($paramObj="") {
        $dataObj=paramsObj();
        $dataObj->request=paramsObj();
        $dataObj->data=paramsObj();
        $dataObj->result=array();

        $final_arr=logInit();
        if($final_arr["error_no"]==0){
            $mixed=parseToArr($paramObj,"mixed",0);
            $params=parseToArr($paramObj,"params",array());
            $messages=parseToArr($paramObj,"messages",array());
            $rules=array(
                'rootPath' => 'require',
                'uploadPath' => 'require',
                'allow_type' => '',
                'max_size' => '',
            );
            $dataDefault=array();
            $dataDefault["mode"]="w";
            $paramsObj=paramsObj();
            $paramsObj->params=$params;
            $paramsObj->mixed=$mixed;
            $paramsObj->rules=$rules;
            $paramsObj->messages=$messages;
            $paramsObj->dataDefault=$dataDefault;
            $checkResult = app("verifyParam")::validatorRequest($paramsObj);
            if($checkResult["error_no"]==0){
                $dataObj->request=$checkResult["result"];
            }else{
                $final_arr=logCallErrorMsg($final_arr,$checkResult);
            }
        }
        if($final_arr["error_no"]==0){
            if($_FILES){
                $dataObj->data->file=$_FILES;
                $dataObj->data->fileCount=count($_FILES);
            }else{
                $final_arr=recordLogMsgLevelTwo(app("errorLevel")::E_WARNING,app("errorCode")::OP_FAIL,lang("file.pleaseSelectTheUploadFile"));
            }
        }
        if($final_arr["error_no"]==0){
            $return=array();
            if($dataObj->data->fileCount >= 2){
                foreach($dataObj->data->file as $val){
                    if($val["file"]["error"] >0){
                        if(in_array($val["file"]["error"],array(1,2,3,4,6,7,8))){
                            $final_arr=recordLogMsgLevelTwo(app("errorLevel")::E_WARNING,app("errorCode")::OP_FAIL,lang("file.fileError".$val["file"]["error"]));
                        }else{
                            $final_arr=recordLogMsgLevelTwo(app("errorLevel")::E_WARNING,app("errorCode")::OP_FAIL,lang("file.fileError"));
                        }
                    }
                    if($final_arr["error_no"]==0){
                        $paramsObj=paramsObj();
                        $paramsObj->params=array(
                            "fileData"=>$val["file"],
                            "uploadPath"=>$dataObj->request->uploadPath,
                            "allow_type"=>$dataObj->request->allow_type,
                            "max_size"=>$dataObj->request->max_size,
                            "rootPath"=>$dataObj->request->rootPath,
                        );
                        $checkResult=$this->uploadOne($paramsObj);
                        if($checkResult["error_no"]==0){
                            $return[]=$checkResult["result"];
                        }else{
                            $final_arr=logCallErrorMsg($final_arr,$checkResult);
                        }
                    }
                    if($final_arr["error_no"]){
                        break;
                    }
                }
            }else{
                $paramsObj=paramsObj();
                $paramsObj->params=array(
                    "fileData"=>$dataObj->data->file["file"],
                    "uploadPath"=>$dataObj->request->uploadPath,
                    "allow_type"=>$dataObj->request->allow_type,
                    "max_size"=>$dataObj->request->max_size,
                    "rootPath"=>$dataObj->request->rootPath,
                );
                $checkResult=$this->uploadOne($paramsObj);
                if($checkResult["error_no"]==0){
                    $return=$checkResult["result"];
                }else{
                    $final_arr=logCallErrorMsg($final_arr,$checkResult);
                }
            }
            if($final_arr["error_no"]==0){
                $final_arr["result"]=$return;
            }
        }
        return $final_arr;
    }

    /**
     * 单文件上传
     * @param string $paramObj
     * @return array
     */
    public function uploadOne($paramObj="") {
        $dataObj=paramsObj();
        $dataObj->request=paramsObj();
        $dataObj->data=paramsObj();
        $dataObj->result=array();

        $final_arr=logInit();
        if($final_arr["error_no"]==0){
            $mixed=parseToArr($paramObj,"mixed",0);
            $params=parseToArr($paramObj,"params",array());
            $messages=parseToArr($paramObj,"messages",array());
            $rules=array(
                'fileData' => 'require',
                'rootPath' => 'require',
                'uploadPath' => 'require',
                'allow_type' => '',
                'max_size' => '',
            );
            $dataDefault=array(
                "allow_type"=>array("ico","webp","jpg","png","jpeg","gif","bmp","mp3","wma","wav","amr","mp4"),
                "max_size"=>1048576 * 20,
            );
            $paramsObj=paramsObj();
            $paramsObj->params=$params;
            $paramsObj->mixed=$mixed;
            $paramsObj->rules=$rules;
            $paramsObj->messages=$messages;
            $paramsObj->dataDefault=$dataDefault;
            $checkResult = app("verifyParam")::validatorRequest($paramsObj);
            if($checkResult["error_no"]==0){
                $dataObj->request=$checkResult["result"];
            }else{
                $final_arr=logCallErrorMsg($final_arr,$checkResult);
            }
        }
        if($final_arr["error_no"]==0){
            $dataObj->data->extname=strtolower($this->getFileType($dataObj->request->fileData["name"]));
            if(!in_array($dataObj->data->extname,$dataObj->request->allow_type)){
                $final_arr=recordLogMsgLevelTwo(app("errorLevel")::E_WARNING,app("errorCode")::OP_FAIL,lang("file.fileTypeNowAllow",["fv1"=>$dataObj->data->extname]));
            }
        }
        if($final_arr["error_no"]==0){
            if($dataObj->request->fileData["size"] > $dataObj->request->max_size){
                $final_arr=recordLogMsgLevelTwo(app("errorLevel")::E_WARNING,app("errorCode")::OP_FAIL,lang("file.fileTooLarge"));
            }
        }
        if($final_arr["error_no"]==0){
            if(!is_uploaded_file($dataObj->request->fileData["tmp_name"]))
            {
                $final_arr=recordLogMsgLevelTwo(app("errorLevel")::E_WARNING,app("errorCode")::OP_FAIL,lang("file.pleaseUsePostToUploadFiles"));
            }
            else
            {
                $fullPath=$dataObj->request->rootPath.$dataObj->request->uploadPath;
                $this->mkdir($fullPath);
                $fileSign=md5_file($dataObj->request->fileData["tmp_name"]);
                $fileName=$fileSign.".".$dataObj->data->extname;
                $filePath=$fullPath."/".$fileName;
                $host=config("app.url","");
                if(is_file($filePath)){
                    $return=array();
                    $return["id"]=md5_file($filePath);
                    $return["relativePath"]=$dataObj->request->uploadPath."/".$fileName;
                    $return["remoteUploadPath"]=$host."/".$return["relativePath"];
                    $final_arr["result"]=$return;
                }else{
                    if(move_uploaded_file($dataObj->request->fileData["tmp_name"],$filePath))
                    {
                        $return=array();
                        $return["id"]=md5_file($filePath);
                        $return["relativePath"]=$dataObj->request->uploadPath."/".$fileName;
                        $return["remoteUploadPath"]=$host."/".$return["relativePath"];
                        $final_arr["result"]=$return;
                    }
                    else
                    {
                        $final_arr=recordLogMsgLevelTwo(app("errorLevel")::E_WARNING,app("errorCode")::OP_FAIL,lang("file.fileMoveFailed"));
                    }
                }
            }
        }
        return $final_arr;
    }

    /**
     * 获取文件内容
     * @param string $paramObj
     * @return array
     */
    public function getFileContent($paramObj="") {
        $dataObj=paramsObj();
        $dataObj->request=paramsObj();
        $dataObj->data=paramsObj();
        $dataObj->result=array();

        $final_arr=logInit();
        if($final_arr["error_no"]==0){
            $mixed=parseToArr($paramObj,"mixed",0);
            $params=parseToArr($paramObj,"params",array());
            $messages=parseToArr($paramObj,"messages",array());
            $rules=array(
                'line' => 'require',
                'filePath' => 'require',
                'offset' => '',
            );
            $dataDefault=array(
                "offset"=>0,
            );
            $paramsObj=paramsObj();
            $paramsObj->params=$params;
            $paramsObj->mixed=$mixed;
            $paramsObj->rules=$rules;
            $paramsObj->messages=$messages;
            $paramsObj->dataDefault=$dataDefault;
            $checkResult = app("verifyParam")::validatorRequest($paramsObj);
            if($checkResult["error_no"]==0){
                $dataObj->request=$checkResult["result"];
            }else{
                $final_arr=logCallErrorMsg($final_arr,$checkResult);
            }
        }
        if($final_arr["error_no"]==0){
            //获取登录数据
            if(!$fp = fopen($dataObj->request->filePath,"r+")){
                $final_arr=recordLogMsgLevelTwo(app("errorLevel")::E_WARNING,app("errorCode")::OP_FAIL,lang("file.cannotOpenFile"));
            }
            if($final_arr["error_no"]==0){
                if (flock($fp, LOCK_EX)) {
                    if($dataObj->request->offset){
                        fseek($fp,intval($dataObj->request->offset));
                    }
                    $returnTxt=array();
                    $i=1;
                    $location=false;
                    if($final_arr["error_no"]==0){
                        while (!feof($fp)) {
                            if($dataObj->request->line >= $i){
                                $buffer = fgets($fp);
                                if($buffer){
                                    $returnTxt[] = $buffer;
                                }
                                $location=ftell($fp);
                            }
                            $i++;
                        }
                    }
                    if($final_arr["error_no"]==0){
                        $return=array();
                        $return["location"]=$location;
                        $return["returnTxt"]=$returnTxt;
                        $final_arr["result"]=$return;
                    }
                    flock($fp, LOCK_UN);    // 释放锁定
                }else{
                    $final_arr=recordLogMsgLevelTwo(app("errorLevel")::E_WARNING,app("errorCode")::OP_FAIL,lang("file.failedToLockFile"));
                }
                fclose($fp);
            }
        }
        return $final_arr;
    }

    /**
     * 检测分片信息
     * @param $uid
     * @return array
     */
    public  function checkMultipartUpload($paramObj="")
    {
        $dataObj=paramsObj();
        $dataObj->request=paramsObj();
        $dataObj->data=paramsObj();
        $dataObj->result=array();

        $final_arr=logInit();
        if($final_arr["error_no"]==0){
            $mixed=parseToArr($paramObj,"mixed",0);
            $params=parseToArr($paramObj,"params",array());
            $messages=parseToArr($paramObj,"messages",array());
            $rules=array(
                'md5value' => 'require',
                'uid' => 'require',
            );
            $dataDefault=array();
            $paramsObj=paramsObj();
            $paramsObj->params=$params;
            $paramsObj->mixed=$mixed;
            $paramsObj->rules=$rules;
            $paramsObj->messages=$messages;
            $paramsObj->dataDefault=$dataDefault;
            $checkResult = app("verifyParam")::validatorRequest($paramsObj);
            if($checkResult["error_no"]==0){
                $dataObj->request=$checkResult["result"];
            }else{
                $final_arr=logCallErrorMsg($final_arr,$checkResult);
            }
        }
        if($final_arr["error_no"]==0){
            $publicPath=publicPath();
            $relativePath="upload/file/{$dataObj->request->uid}";
            $relativeTmpPath=$relativePath."/upload_tmp/{$dataObj->request->md5value}";
            $targetDir = $publicPath.$relativeTmpPath; //存放存片的数据

            $temp=array();
            $final=array();
            $final["chunks"]="";
            $final["isHas"]=0;
            if (file_exists($targetDir))
            {
                // 找出上传成功的所有文件
                $block_info=scandir($targetDir);
                // 除去无用文件
                foreach ($block_info as $key => $val)
                {
                    if (preg_match('/\.(part)$/', $val))
                    {
                        $pathParts=pathinfo($val);
                        $temp[]=$pathParts["filename"];
                    }
                }
            }
            if($temp)
            {
                sort($temp);
                $final["isHas"]=1;
                $final["chunks"]=$temp;
            }
            $final_arr["result"]=$final;
        }
        return $final_arr;
    }

    /**
     * 百度上传插件
     * @return mixed
     */
    public function webUploader($paramObj="")
    {
        $dataObj=paramsObj();
        $dataObj->request=paramsObj();
        $dataObj->data=paramsObj();
        $dataObj->result=array();

        $final_arr=logInit();
        if($final_arr["error_no"]==0){
            $mixed=parseToArr($paramObj,"mixed",0);
            $params=parseToArr($paramObj,"params",array());
            $messages=parseToArr($paramObj,"messages",array());
            $rules=array(
                'md5value' => '',
                'chunk' => '',
            );
            $dataDefault=array();
            $paramsObj=paramsObj();
            $paramsObj->params=$params;
            $paramsObj->mixed=$mixed;
            $paramsObj->rules=$rules;
            $paramsObj->messages=$messages;
            $paramsObj->dataDefault=$dataDefault;
            $checkResult = app("verifyParam")::validatorRequest($paramsObj);
            if($checkResult["error_no"]==0){
                $dataObj->request=$checkResult["result"];
            }else{
                $final_arr=logCallErrorMsg($final_arr,$checkResult);
            }
        }
        if($final_arr["error_no"]==0){
            if($dataObj->request->md5value && isset($dataObj->request->chunk)){
                $checkResult=$this->multipartUpload($paramObj);
                if($checkResult["error_no"]==0){
                    $final_arr["result"]=$checkResult["result"];
                }else{
                    $final_arr=logCallErrorMsg($final_arr,$checkResult);
                }
            }else{
                $checkResult=$this->fileUpload($paramObj);
                if($checkResult["error_no"]==0){
                    $final_arr["result"]=$checkResult["result"];
                }else{
                    $final_arr=logCallErrorMsg($final_arr,$checkResult);
                }
            }
        }
        return $final_arr;
    }

    /**
     * 分片上传执行
     * @return mixed
     */
    public function multipartUpload($paramObj="")
    {
        header("Expires: Mon, 26 Jul 1997 05:00:00 GMT");
        header("Last-Modified: " . gmdate("D, d M Y H:i:s") . " GMT");
        header("Cache-Control: no-store, no-cache, must-revalidate");
        header("Cache-Control: post-check=0, pre-check=0", false);
        header("Pragma: no-cache");

        $dataObj=paramsObj();
        $dataObj->request=paramsObj();
        $dataObj->data=paramsObj();
        $dataObj->result=array();

        $final_arr=logInit();
        if($final_arr["error_no"]==0){
            $mixed=parseToArr($paramObj,"mixed",0);
            $params=parseToArr($paramObj,"params",array());
            $messages=parseToArr($paramObj,"messages",array());
            $rules=array(
                'md5value' => 'require',
                'id' => 'require',
                'name' => 'require',
                'chunk' => 'require|integer',
                'size' => 'require|integer',
                'chunks' => 'require|integer',
                'rootPath' => 'require',
                'uploadPath' => 'require',
            );
            $dataDefault=array();
            $paramsObj=paramsObj();
            $paramsObj->params=$params;
            $paramsObj->mixed=$mixed;
            $paramsObj->rules=$rules;
            $paramsObj->messages=$messages;
            $paramsObj->dataDefault=$dataDefault;
            $checkResult = app("verifyParam")::validatorRequest($paramsObj);
            if($checkResult["error_no"]==0){
                $dataObj->request=$checkResult["result"];
            }else{
                $final_arr=logCallErrorMsg($final_arr,$checkResult);
            }
        }
        if($final_arr["error_no"]==0){
            $relativePath=$dataObj->request->uploadPath;
            $relativeTmpPath=$relativePath."/tmp/{$dataObj->request->md5value}";
            $absolutePath=$dataObj->request->rootPath.$relativePath; //存放游戏的数据
            $targetDir = $dataObj->request->rootPath.$relativeTmpPath; //存放存片的数据

            if($final_arr["error_no"]==0)
            {
                $flag=$this->mkdir($absolutePath);
                if(!$flag)
                {
                    $final_arr=recordLogMsgLevelTwo(app("errorLevel")::E_WARNING,app("errorCode")::OP_FAIL,"创建目录失败","目录： {$absolutePath}");
                }
            }
            if($final_arr["error_no"]==0)
            {
                $flag=$this->mkdir($targetDir);
                if(!$flag)
                {
                    $final_arr=recordLogMsgLevelTwo(app("errorLevel")::E_WARNING,app("errorCode")::OP_FAIL,"创建目录失败","目录： {$targetDir}");
                }
            }
            if($final_arr["error_no"]==0)
            {
                if(!file_exists("{$targetDir}/{$dataObj->request->chunk}.part"))
                {
                    // Open temp file
                    if (!$out = @fopen("{$targetDir}/{$dataObj->request->chunk}.parttmp", "wb"))
                    {
                        $final_arr=recordLogMsgLevelTwo(app("errorLevel")::E_WARNING,app("errorCode")::OP_FAIL,"写入失败","文件 {$dataObj->request->chunk}.parttmp 不能写入");
                    }
                    if($final_arr["error_no"]==0)
                    {
                        if (!empty($_FILES))
                        {
                            if ($_FILES["file"]["error"])
                            {
                                $final_arr=recordLogMsgLevelTwo(app("errorLevel")::E_WARNING,app("errorCode")::OP_FAIL,lang("sys.opFail"),lang("file.fileError".$_FILES["file"]["error"]),$_FILES);
                            }
                            if($final_arr["error_no"]==0)
                            {
                                if (!is_uploaded_file($_FILES["file"]["tmp_name"]))
                                {
                                    $final_arr=recordLogMsgLevelTwo(app("errorLevel")::E_WARNING,app("errorCode")::OP_FAIL,lang("file.fileMoveFailed"));
                                }
                            }
                            if($final_arr["error_no"]==0)
                            {
                                if (!$in = @fopen($_FILES["file"]["tmp_name"], "rb"))
                                {
                                    $final_arr=recordLogMsgLevelTwo(app("errorLevel")::E_WARNING,app("errorCode")::OP_FAIL,lang("sys.opFail"),"打开目录失败：{$_FILES["file"]["tmp_name"]}",$_FILES);
                                }
                            }
                        }
                        else
                        {
                            if (!$in = @fopen("php://input", "rb"))
                            {
                                $final_arr=recordLogMsgLevelTwo(app("errorLevel")::E_WARNING,app("errorCode")::OP_FAIL,lang("sys.opFail"),"打开目录失败：php://input");
                            }
                        }
                    }
                    if($final_arr["error_no"]==0)
                    {
                        while ($buff = fread($in, 4096))
                        {
                            fwrite($out, $buff);
                        }
                        @fclose($out);
                        @fclose($in);
                        rename("{$targetDir}/{$dataObj->request->chunk}.parttmp", "{$targetDir}/{$dataObj->request->chunk}.part");
                    }
                }
            }
        }
        if($final_arr["error_no"]==0){
            if($dataObj->request->chunk == $dataObj->request->chunks -1){
                //合并代码
                $paramsObj=paramsObj();
                $paramsObj->params=array(
                    'md5value' => $dataObj->request->md5value,
                    'name' => $dataObj->request->name,
                    'chunks' => $dataObj->request->chunks,
                    'rootPath' => $dataObj->request->rootPath,
                    'uploadPath' => $dataObj->request->uploadPath,
                );
                $checkResult=$this->mergeMultipartUpload($paramsObj);
                if($checkResult["error_no"]==0){
                    $final_arr["result"]=$checkResult["result"];
                }else{
                    $final_arr=logCallErrorMsg($final_arr,$checkResult);
                }
            }
        }
        return $final_arr;
    }

    /**
     * 合并文件
     * @param $uid
     */
    public function mergeMultipartUpload($paramObj="")
    {
        $dataObj=paramsObj();
        $dataObj->request=paramsObj();
        $dataObj->data=paramsObj();
        $dataObj->result=array();

        $final_arr=logInit();
        if($final_arr["error_no"]==0){
            $mixed=parseToArr($paramObj,"mixed",0);
            $params=parseToArr($paramObj,"params",array());
            $messages=parseToArr($paramObj,"messages",array());
            $rules=array(
                'md5value' => 'require',
                'name' => 'require',
                'chunks' => 'require|integer',
                'rootPath' => 'require',
                'uploadPath' => 'require',
            );
            $dataDefault=array();
            $paramsObj=paramsObj();
            $paramsObj->params=$params;
            $paramsObj->mixed=$mixed;
            $paramsObj->rules=$rules;
            $paramsObj->messages=$messages;
            $paramsObj->dataDefault=$dataDefault;
            $checkResult = app("verifyParam")::validatorRequest($paramsObj);
            if($checkResult["error_no"]==0){
                $dataObj->request=$checkResult["result"];
            }else{
                $final_arr=logCallErrorMsg($final_arr,$checkResult);
            }
        }
        if($final_arr['error_no']==0)
        {
            //重新编译名
            $extend = pathinfo( $dataObj->request->name );
            $extend = strtolower ( $extend [ "extension" ]);

            $relativePath=$dataObj->request->uploadPath;
            $relativeTmpPath=$relativePath."/tmp/{$dataObj->request->md5value}";
            $absolutePath=$dataObj->request->rootPath.$relativePath; //存放游戏的数据
            $targetDir = $dataObj->request->rootPath.$relativeTmpPath; //存放存片的数据

            $relFilePath=$relativePath.'/'.$dataObj->request->md5value.'.'.$extend;
            $filePath=$absolutePath.'/'.$dataObj->request->md5value.'.'.$extend;

            if($final_arr["error_no"]==0)
            {
                $done = true;
                for ($index = 0; $index < $dataObj->request->chunks; $index++)
                {
                    if (!file_exists("{$targetDir}/{$index}.part"))
                    {
                        $done = false;
                        break;
                    }
                }
                if ($done)
                {
                    if (!$out = @fopen($filePath, "wb"))
                    {
                        $final_arr=recordLogMsgLevelTwo(app("errorLevel")::E_WARNING,app("errorCode")::OP_FAIL,lang("sys.opFail"),"打开文件失败：{$filePath}");
                    }
                    if($final_arr["error_no"]==0)
                    {
                        if ( flock($out, LOCK_EX) )
                        {
                            for( $index = 0; $index < $dataObj->request->chunks; $index++ )
                            {
                                if (!$in = @fopen("{$targetDir}/{$index}.part", "rb"))
                                {
                                    break;
                                }

                                while ($buff = fread($in, 4096))
                                {
                                    fwrite($out, $buff);
                                }
                                @fclose($in);
                                @unlink("{$targetDir}/{$index}.part");
                            }
                            flock($out, LOCK_UN);
                            @rmdir($relativeTmpPath);
                        }
                    }
                    @fclose($out);
                }else{
                    $final_arr=recordLogMsgLevelTwo(app("errorLevel")::E_WARNING,app("errorCode")::OP_FAIL,"文件不完整");
                }
            }
            if($final_arr["error_no"]==0)
            {
                $filemd5=md5_file($filePath);
                if($filemd5!=$dataObj->request->md5value)
                {
                    $final_arr=recordLogMsgLevelTwo(app("errorLevel")::E_WARNING,app("errorCode")::OP_FAIL,"上传的包不完整","校验未通过：{$filemd5} != {$dataObj->request->md5value}");
                }
            }
            if($final_arr["error_no"]==0)
            {
                $result=array();
                $result["relativePath"]=$relFilePath;
                $result["remoteUploadPath"]=config("app.url","")."/".$result["relativePath"];
                $final_arr["result"]=$result;
            }
        }
        return $final_arr;
    }

    public function __call($name,$arguments)
    {
        return recordLogMsgLevelTwo(app("errorLevel")::E_WARNING,app("errorCode")::UNDEFINED_METHOD,lang("sys.noMethodDefined"),$name,$arguments);
    }
}

